using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace PBR.Controls
{
    public partial class StrokeProperties : UserControl
    {
        private Scene scene;
        private MainForm mainForm;

        public StrokeProperties(Scene scene, MainForm mainForm)
        {
            InitializeComponent();

            this.scene = scene;
            this.mainForm = mainForm;
        }

        public void InitStroke()
        {
            if (scene.Painting.ActiveLayer.SelectedStroke != null)
            {
                Color baseColor = scene.Painting.ActiveLayer.SelectedStroke.BaseColor;
                
                // init alpha
                alphaNumericUpDown.Value = baseColor.A;
                alphaScrollBar.Value = baseColor.A;
            }
            colorPreviewPanel.Invalidate();
            Invalidate();
        }

        private void colorPreviewPanel_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if (scene.Painting.ActiveLayer.SelectedStroke != null)
            {
                g.FillRectangle(new SolidBrush(scene.Painting.ActiveLayer.SelectedStroke.BaseColor),
                    new Rectangle(0, 0, colorPreviewPanel.Width, colorPreviewPanel.Height));
            }
            else
            {
                g.FillRectangle(new SolidBrush(Color.Gray),
                    new Rectangle(0, 0, colorPreviewPanel.Width, colorPreviewPanel.Height));
            }
            g.Flush();
        }

        #region Color

        private void colorPreviewPanel_DoubleClick(object sender, EventArgs e)
        {
            if (scene.Painting.ActiveLayer.SelectedStroke == null)
                return;
            PBR.Forms.ColorChooser.ColorChooserCSharp.ColorChooser1 colorChooser =
                new PBR.Forms.ColorChooser.ColorChooserCSharp.ColorChooser1();
            colorChooser.Color = scene.Painting.ActiveLayer.SelectedStroke.BaseColor;
            
            if (colorChooser.ShowDialog() == DialogResult.OK)
            {
                scene.Painting.ActiveLayer.SelectedStroke.BaseColor = colorChooser.Color;
            }
            colorPreviewPanel.Invalidate();

            UpdatePreviewControl();
        }

        #endregion

        #region Alpha

        private void alphaPanel_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            int color = 0;
            if (scene.Painting.ActiveLayer.SelectedStroke != null)
                color = scene.Painting.ActiveLayer.SelectedStroke.BaseColor.A;
            g.FillRectangle(new SolidBrush(Color.FromArgb(255, color, color, color)),
                new Rectangle(0, 0, colorPreviewPanel.Width, colorPreviewPanel.Height));
            g.Flush();
        }

        private void alphaScrollBar_ValueChanged(object sender, EventArgs e)
        {
            Color baseColor = scene.Painting.ActiveLayer.SelectedStroke.BaseColor;
            scene.Painting.ActiveLayer.SelectedStroke.BaseColor =
                Color.FromArgb(alphaScrollBar.Value,
                baseColor.R, baseColor.G, baseColor.B);
            alphaNumericUpDown.Value = alphaScrollBar.Value;
            alphaPanel.Invalidate();
            //UpdatePreviewControl();
        }

        private void alphaNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            Color baseColor = scene.Painting.ActiveLayer.SelectedStroke.BaseColor;
            scene.Painting.ActiveLayer.SelectedStroke.BaseColor =
                Color.FromArgb((int)alphaNumericUpDown.Value,
                baseColor.R, baseColor.G, baseColor.B);
            alphaScrollBar.Value = (int)alphaNumericUpDown.Value;
            alphaPanel.Invalidate();
            //UpdatePreviewControl();
        }

        #endregion

        #region Draw Order

        /// <summary>
        /// Brings the selected stroke to the front of the draw list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bringToFrontbutton_Click(object sender, EventArgs e)
        {
            if (scene.Painting.ActiveLayer.SelectedStroke == null)
                return;

            Stroke selectedStroke = scene.Painting.ActiveLayer.SelectedStroke;
            scene.Painting.StrokeList.Remove(selectedStroke);
            selectedStroke.ZOrder = scene.Painting.StrokeList.Count;
            scene.Painting.StrokeList.Insert(selectedStroke.ZOrder, selectedStroke);
            UpdatePreviewControl();
        }

        /// <summary>
        /// Bring the stroke forward 10%
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bringForwardButton_Click(object sender, EventArgs e)
        {
            if (scene.Painting.ActiveLayer.SelectedStroke == null)
                return;

            Stroke selectedStroke = scene.Painting.ActiveLayer.SelectedStroke;
            scene.Painting.StrokeList.Remove(selectedStroke);
            selectedStroke.ZOrder += (int)(scene.Painting.StrokeList.Count * 0.1);
            if (selectedStroke.ZOrder > scene.Painting.StrokeList.Count)
                selectedStroke.ZOrder = scene.Painting.StrokeList.Count;
            scene.Painting.StrokeList.Insert(selectedStroke.ZOrder, selectedStroke);
            UpdatePreviewControl();
        }

        private void pushBackwardsButton_Click(object sender, EventArgs e)
        {
            if (scene.Painting.ActiveLayer.SelectedStroke == null)
                return;

            Stroke selectedStroke = scene.Painting.ActiveLayer.SelectedStroke;
            scene.Painting.StrokeList.Remove(selectedStroke);
            selectedStroke.ZOrder -= (int)(scene.Painting.StrokeList.Count * 0.1);
            if (selectedStroke.ZOrder < 0)
                selectedStroke.ZOrder = 0;
            scene.Painting.StrokeList.Insert(selectedStroke.ZOrder, selectedStroke);
            UpdatePreviewControl();
        }

        private void pushToBottomButton_Click(object sender, EventArgs e)
        {
            if (scene.Painting.ActiveLayer.SelectedStroke == null)
                return;

            Stroke selectedStroke = scene.Painting.ActiveLayer.SelectedStroke;
            scene.Painting.StrokeList.Remove(selectedStroke);
            selectedStroke.ZOrder = 0;
            scene.Painting.StrokeList.Insert(selectedStroke.ZOrder, selectedStroke);
            UpdatePreviewControl();
        }

        #endregion

        #region Helper Functions

        private void UpdatePreviewControl()
        {
            // redraw preview paint panel
            mainForm.previewerControl.PaintPreview();
            mainForm.previewerControl.paintPanel.Invalidate();
        }

        #endregion

    }
}
